package com.hitqz.robot.dispatch.netty.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.google.common.cache.Cache;
import com.google.common.collect.Maps;
import com.hitqz.robot.api.business.dto.RobotClientSummaryDto;
import com.hitqz.robot.api.business.entity.RobotEntity;
import com.hitqz.robot.api.business.enums.WorkStatusEnum;
import com.hitqz.robot.dispatch.netty.factory.AlgorithmFactory;
import com.hitqz.robot.dispatch.netty.service.DispatchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author xupkun
 * @date 2024/7/28
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DispatchServiceImpl implements DispatchService {

    private final AlgorithmFactory algorithmFactory;

    /**
     * key-groupid
     * value - robotId
     */
    private Map<Integer, String> lastExecutedRobotMap = Maps.newHashMap();


    public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10,20,
            1L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(20),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.DiscardPolicy());


    @Override
    public String findExecuteRobot(Integer groupId) {
        // 使用随机机器人
        String executeRobot = null;

        // 初始化 Map 以避免 NPE
        Cache<String, RobotClientSummaryDto> posInfoDtoCache = SpringUtil.getBean("robotCache");
        Cache<Integer, List<RobotEntity>> robotDispatch = SpringUtil.getBean("robotDispatch");

        // 查询当前组下的所有机器人
        List<RobotEntity> currentGroupRobot = robotDispatch.getIfPresent(groupId);

        // 检查列表是否为空
        if (currentGroupRobot == null) {
            log.error("not found groupId : " + groupId);
            return null;
        }
        // 过滤出可用的机器人
        log.info("过滤前可用的机器人数量；{}", currentGroupRobot.size());
        List<String> robotSns = currentGroupRobot.stream()
                .filter(t -> {
                    RobotClientSummaryDto robotClientSummaryDto = posInfoDtoCache.getIfPresent(t.getRobotSn());
                    if (robotClientSummaryDto == null) {
                        return false;
                    }
                    log.info("robot {} workStatus {} ", t.getRobotSn(), robotClientSummaryDto.getStatus().getWorkStatus());
                    return robotClientSummaryDto.getStatus().getWorkStatus() == Integer.parseInt(WorkStatusEnum.FREE.getCode());
                })
                .map(RobotEntity::getRobotSn)
                .toList();
        log.info("可用的机器人数量:" + robotSns.size());
        if (CollectionUtil.isEmpty(robotSns)) {
            return null;
        }
        // 选择一个未执行过的机器人
        for (String robotSn : robotSns) {
            if (!Objects.equals(robotSn, lastExecutedRobotMap.get(groupId))) {
                executeRobot = robotSn;
                break;
            }
        }
        log.info("是否查询出可用机器人:{}", executeRobot);
        // 如果没有找到新的机器人，则使用上次执行的机器人
        if (executeRobot == null) {
            executeRobot = lastExecutedRobotMap.get(groupId);
            if (executeRobot != null) {
                log.info("use last robot to execute task: " + executeRobot);
            }
        }
        // 更新最后执行的机器人
        if (executeRobot != null) {
            lastExecutedRobotMap.put(groupId, executeRobot);
        }
        log.info("最后查询到执行任务的机器人: {}", executeRobot);

        return executeRobot;
    }



    @Override
    public void calAlgorithm(String algorithm, Integer groupId, List<RobotEntity> robotEntityList) {
        // 计算是否可能发生碰撞，不涉及主要算法
        //threadPool.execute(()-> {
        //    Cache<String, RobotClientSummaryDto> posInfoDtoCache = SpringUtil.getBean("robotCache");
        //    // 两两比较-计算
        //    for (String key: posInfoDtoCache.asMap().keySet()) {
        //        RobotClientSummaryDto firstCar = posInfoDtoCache.getIfPresent(key);
        //        for(String nextKey: posInfoDtoCache.asMap().keySet()) {
        //            RobotClientSummaryDto nextCar = posInfoDtoCache.getIfPresent(nextKey);
        //            if (!Objects.equals(key, nextCar)) {
        //                // 按照车体计算  后续完善
        //                // 1. 两车相向运动 2- 两车相背运动 3-同向运动
        //
        //            }
        //        }
        //    }
        //});
        threadPool.execute(()-> {
            algorithmFactory.getRoutingStrategy(algorithm).calculate(groupId, robotEntityList);
        });
    }
}
